import { Vue, Prop, Watch } from 'vue-property-decorator'
import { ComponentModel } from '@TG/interface'
import { TyperChunkMeta } from '@TG/interface/types/typer'
import { buildDOMKey } from '@TG/kit/element'
import router from '@TG/kit/router'
import { isEmpty, isNotEmpty } from '@TG/kit/validate'
import { appModule } from '@TG/store/modules/app'
import typer from '../index'

/*
prop 列表
  chunkKey: string 块键
*/
export default abstract class extends Vue {
  @Prop({ type: String, required: true }) protected chunkKey!: string

  protected typerInitialized: boolean = false
  protected routeName: string = ''
  protected components: ComponentModel[] = []
  protected metaStorer: Map<string, TyperChunkMeta> = new Map<string, TyperChunkMeta>()

  created() {
    this.typerInitialized = appModule.typerInitialized
    if (this.typerInitialized === true) {
      this.initTemplate()
    }
  }

  @Watch('$store.globalData.typerInitialized')
  watchTyperInitialized(value: boolean) {
    if (value === true) {
      this.typerInitialized = true
      this.initTemplate()
    }
  }

  protected initTemplate() {
    const currentRoute = router.currentRoute
    this.routeName = currentRoute.name || ''
    let chunkKey = this.chunkKey
    if (isEmpty(chunkKey)) {
      chunkKey = this.routeName
    }
    const chunk = typer.getChunk(chunkKey)
    this.components = chunk?.components || []
    this.metaStorer = chunk?.metaStorer || new Map<string, TyperChunkMeta>()
  }

  public abstract getTemplateName(): string

  public abstract getMainData(): any

  public abstract refresh(): void

  public buildDOMKey(cm: ComponentModel, index: number = 0) {
    return buildDOMKey(cm, index)
  }

  /**
   * 获取元信息
   * @param vm Vue 实例（this）
   * @param metaType 元信息类型
   * @param defaultValue 元信息默认值 [可空]
   */
  public getMeta(vm: Vue, metaType: string, defaultValue?: any) {
    let meta = defaultValue || this.getMetaDefaultValue(vm, metaType)
    const chunkMeta = this.metaStorer.get(metaType)
    if (isNotEmpty(chunkMeta)) {
      meta = (chunkMeta as TyperChunkMeta).metaFunc(vm)
      if (isNotEmpty(meta)) {
        meta['chunkKey'] = this.chunkKey
        meta['routerName'] = this.routeName
        meta['metaType'] = metaType
      }
    }
    return meta
  }

  private getMetaDefaultValue(vm: Vue, metaType: string): any {
    const templateName = this.getTemplateName()
    const defaultValue: any = {}
    return defaultValue
  }

  public abstract defaultRef(): string

  public ref(key: string = this.defaultRef()) {
    return this.$refs[`ref-${key}`]
  }

  public refs() {
    return this.$refs
  }
}
